#ifndef _SERVER_H_
#define _SERVER_H_

/*----------------------------------------------------------------------------*/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>

/* Signals */
#include <signal.h>
#include <sys/wait.h>

/* Fork */
#include <sys/types.h>
#include <unistd.h>

#include "../clsv/ipc/sem.h"
#include "../clsv/clsv.h"
#include "../clsv/error.h"
#include "../superADT/transport/transADT.h"
#include "../superADT/sessADT.h"


/*----------------------------------------------------------------------------*/

#define INSTANCE_KEY_FIFO	0x122
#define INSTANCE_KEY_MSG	0x222
#define INSTANCE_KEY_SHM	0x322
#define INSTANCE_KEY_TCP	0x422
#define INSTANCE_PERMS		0644

#define KEY_FIFO_SND		"/tmp/chat_serv_ticket"
#define KEY_FIFO_RCV		"/tmp/chat_serv_listen"
#define KEY_MSG				0x22
#define KEY_SHM_SND			0x1026
#define KEY_SHM_RCV			0x1027
#define KEY_TCP				"12345"

#define USE_FIFO_STR		"fifo"
#define USE_MSG_STR			"msg"
#define USE_TCP_STR			"tcp"
#define USE_SHM_STR			"shm"

#define _SERVER_ 			1
#define _CLIENT_ 			!SERVER

/*----------------------------------------------------------------------------*/

#define forever for(;;)

/*----------------------------------------------------------------------------*/

typedef struct TsrvData
{
	int ipc;			/* Communication method to use */
	int instance;		/* Semaphore key value */
	void *port;			/* "Port"of the IPC to use */
	sessADT srvSess;	/* Server session */
	sessADT cliSess;	/* Client session */
}TsrvData;

typedef struct Tclient
{
	int type;
} Tclient;

typedef struct threadinfo {
	unsigned long parentid;
	sessADT session;
	pthread_mutex_t mutexsnd;
} threadInfoT;

/*----------------------------------------------------------------------------*/

typedef void (*sighandler_t)(int);

/*----------------------------------------------------------------------------*/
/* All the funcions return ERROR_OK if no error, else non zero */
/* The default error is ERROR_DEFAULT */

int getConf(int argc, char ** argv, TsrvData *srvData);

int checkInstance(TsrvData *srvData);

void exitServer(int s);

int intrHandler(void);

int server(TsrvData *srvData);


/* SIGINT handler */
void siginthandler(int sig);

/* SIGUSR1 handler */
void sigusr1handler(int sig);

void process_conn(CLSV_BUFFER * data, int * session, threadInfoT * tinfo);
void process_lists(CLSV_BUFFER * data, int * session, threadInfoT * tinfo);
void process_listu(CLSV_BUFFER * data, int * session, threadInfoT * tinfo);
void process_disc(CLSV_BUFFER * data, int * session, threadInfoT * tinfo);
void process_info(CLSV_BUFFER * data, int * session, threadInfoT * tinfo);
void process_MessR(CLSV_BUFFER * data, int * session, threadInfoT * tinfo);
void process_MessS(CLSV_BUFFER * data, int * session, threadInfoT * tinfo);


/*----------------------------------------------------------------------------*/

#endif
